package com.ruizhong.centercontroll.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruizhong.centercontroll.dao.TSliderMapper;
import com.ruizhong.centercontroll.entity.TCommand;
import com.ruizhong.centercontroll.entity.TSlider;
import com.ruizhong.centercontroll.service.TCommandService;
import com.ruizhong.centercontroll.service.TSliderService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.websocket.EncodeException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TSliderServiceImpl extends ServiceImpl<TSliderMapper, TSlider> implements TSliderService {

    @Autowired
    private TCommandService tCommandService;

    @Override
    @Transactional
    public void saveNewSliderList(List<Map<String, Object>> sliderList, Integer pageId, boolean isNew) {
        deleteSlidersByPageId(pageId);
        final HashMap<Integer, List<Map<String, Object>>> sliderIdMapSlideCommandList = new HashMap<>();
        final HashMap<Integer, List<Map<String, Object>>> sliderIdMapInitCommandList = new HashMap<>();
        sliderList.forEach(sliderOB -> {
            Object sliderVariable = sliderOB.get("sliderVariable");
            Object lastSlideName = sliderOB.get("lastSlideName");
            Object keepLast = sliderOB.get("keepLast");
            Object vertical = sliderOB.get("vertical");
            TSlider tSlider = new TSlider();
            tSlider.setPageId(pageId);
            tSlider.setValue(Double.parseDouble(sliderOB.get("value").toString()));
            tSlider.setW(Double.parseDouble(sliderOB.get("w").toString()));
            tSlider.setH(Double.parseDouble(sliderOB.get("h").toString()));
            tSlider.setX(sliderOB.get("x")==null?0:Double.parseDouble(sliderOB.get("x").toString()));
            tSlider.setY(sliderOB.get("y")==null?0:Double.parseDouble(sliderOB.get("y").toString()));
            tSlider.setZ(Integer.parseInt(sliderOB.get("z").toString()));
            tSlider.setSliderVariable(sliderVariable == null ? null : sliderVariable.toString());
            tSlider.setLastSlideName(lastSlideName == null ? null : lastSlideName.toString());
            tSlider.setKeepLastData(keepLast == null ? 0 : (Boolean) keepLast ? 1 : 0);
            tSlider.setVerticalData(vertical == null ? null : (Boolean) vertical ? 1 : 0);
            Object displayVariableName = sliderOB.get("displayVariableName");
            Object displayVariableValue = sliderOB.get("displayVariableValue");
            tSlider.setDisplayVariableName(displayVariableName == null ? null : displayVariableName.toString());
            tSlider.setDisplayVariableValue(displayVariableValue == null ? null : displayVariableValue.toString());
            Object conditionShow = sliderOB.get("conditionShow");
            tSlider.setConditionShowData(conditionShow == null ? null : (Boolean) conditionShow ? 1 : 0);
            tSlider.setMin(Integer.parseInt(sliderOB.get("min").toString()));
            tSlider.setMax(Integer.parseInt(sliderOB.get("max").toString()));
            tSlider.setRailBackground(sliderOB.get("railBackground").toString());
            tSlider.setRailProgressColor(sliderOB.get("railProgressColor").toString());
            tSlider.setRailBorderWidth(Double.parseDouble(sliderOB.get("railBorderWidth").toString()));
            tSlider.setRailBorderColor(sliderOB.get("railBorderColor").toString());
            tSlider.setRailBorderRoundCorner(Double.parseDouble(sliderOB.get("railBorderRoundCorner").toString()));
            Object sliderBackground = sliderOB.get("sliderBackground");
            tSlider.setSliderBackground(sliderBackground == null ? null : sliderBackground.toString());
            Object sliderBackgroundColor = sliderOB.get("sliderBackgroundColor");
            tSlider.setSliderBackgroundColor(sliderBackgroundColor == null ? null : sliderBackgroundColor.toString());
            tSlider.setSliderWidth(Double.parseDouble(sliderOB.get("sliderWidth").toString()));
            tSlider.setSliderHeight(Double.parseDouble(sliderOB.get("sliderHeight").toString()));
            tSlider.setSliderMarginTop(Double.parseDouble(sliderOB.get("sliderMarginTop").toString()));
            tSlider.setSliderMarginBottom(Double.parseDouble(sliderOB.get("sliderMarginBottom").toString()));
            tSlider.setSliderMarginLeft(Double.parseDouble(sliderOB.get("sliderMarginLeft").toString()));
            tSlider.setSliderMarginRight(Double.parseDouble(sliderOB.get("sliderMarginRight").toString()));
            Object sliderBorderRadius = sliderOB.get("sliderBorderRadius");
            tSlider.setSliderBorderRadius(sliderBorderRadius == null ? null : Double.parseDouble(sliderBorderRadius.toString()));
            List<Map<String, Object>> slideCommandList = null;
            List<Map<String, Object>> initCommandList = null;
            Map logicGraph = (Map) sliderOB.get("logicGraph");
            if (!isNew) {
                slideCommandList = (List<Map<String, Object>>) sliderOB.get("slideCommandList");
                initCommandList = (List<Map<String, Object>>) sliderOB.get("initCommandList");
            } else {
                ObjectMapper mapper = new ObjectMapper();
                try {
                    String logicGraphString = mapper.writeValueAsString(logicGraph);
                    tSlider.setLogicGraphData(logicGraphString);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                Map<String, List> typeMapCommandList = TCommandServiceImpl.getCommandsByGraph(logicGraph);
                slideCommandList = typeMapCommandList.get("slideCommandList");
                initCommandList = typeMapCommandList.get("initCommandList");
            }
            save(tSlider);
            sliderIdMapSlideCommandList.put(tSlider.getId(), slideCommandList);
            sliderIdMapInitCommandList.put(tSlider.getId(), initCommandList);
        });
        Runnable runnable = new Runnable() {
            public void run() {
                tCommandService.saveCommandList("SLIDER", "slide", sliderIdMapSlideCommandList);
                tCommandService.saveCommandList("SLIDER", "init", sliderIdMapInitCommandList);
            }
        };
        new Thread(runnable).start();
    }

    @Override
    public void deleteSlidersByPageId(Integer pageId) {
        List<TSlider> list = lambdaQuery()
                .select(TSlider::getId)
                .eq(TSlider::getPageId, pageId)
                .list();
        Set<Integer> sliderIds = list.stream().map(TSlider::getId).collect(Collectors.toSet());

        QueryWrapper<TSlider> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.lambda().eq(TSlider::getPageId, pageId);
        remove(deleteWrapper);
        tCommandService.delCommandsByMain(sliderIds, "SLIDER");
    }

    @Override
    public List<TSlider> getSlidersByPageId(Integer pageId, Double pageWidth, Double pageHeight, Double aimPageWidth, Double aimPageHeight, Boolean display) throws JsonProcessingException {
        List<TSlider> tSliders = lambdaQuery()
                .eq(TSlider::getPageId, pageId)
                .list();
        for (TSlider tSlider : tSliders) {
            if (!display) {
                String logicGraphData = tSlider.getLogicGraphData();
                if (!StringUtils.isEmpty(logicGraphData)){
                    ObjectMapper mapper = new ObjectMapper();
                    Map map = mapper.readValue(logicGraphData, Map.class);
                    tSlider.setLogicGraph(map);
                }
                List<TCommand> slideCommands = tCommandService.getCommandListByMain(tSlider.getId(), tSlider.getType(), "slide");
                List<TCommand> initCommands = tCommandService.getCommandListByMain(tSlider.getId(), tSlider.getType(), "init");
                slideCommands = tCommandService.fillTCommands(slideCommands);
                initCommands = tCommandService.fillTCommands(initCommands);
                tSlider.setSlideCommandList(slideCommands);
                tSlider.setInitCommandList(initCommands);
            }
            if (aimPageHeight != -1 && aimPageWidth != -1) {
                tSlider.setW(Math.floor((tSlider.getW() * aimPageWidth) / pageWidth));
                tSlider.setH(Math.floor((tSlider.getH() * aimPageHeight) / pageHeight));
                tSlider.setX(Math.floor((tSlider.getX() * aimPageWidth) / pageWidth));
                tSlider.setY(Math.floor((tSlider.getY() * aimPageHeight) / pageHeight));
                tSlider.setRailBorderWidth(Math.floor((tSlider.getRailBorderWidth() * aimPageWidth) / pageWidth));
                tSlider.setSliderWidth(Math.floor((tSlider.getSliderWidth() * aimPageWidth) / pageWidth));
                tSlider.setSliderHeight(Math.floor((tSlider.getSliderHeight() * aimPageHeight) / pageHeight));
                tSlider.setSliderMarginTop(Math.floor((tSlider.getSliderMarginTop() * aimPageHeight) / pageHeight));
                tSlider.setSliderMarginBottom(Math.floor((tSlider.getSliderMarginBottom() * aimPageHeight) / pageHeight));
                tSlider.setSliderMarginLeft(Math.floor((tSlider.getSliderMarginLeft() * aimPageWidth) / pageWidth));
                tSlider.setSliderMarginRight(Math.floor((tSlider.getSliderMarginRight() * aimPageWidth) / pageWidth));
            }

            tSlider.setVertical(tSlider.getVerticalData() == 1);
            tSlider.setConditionShow(tSlider.getConditionShowData() == null ? false : tSlider.getConditionShowData() == 1);
            tSlider.setKeepLast(tSlider.getKeepLastData() == 1);

        }
        return tSliders;
    }

    @Override
    public void executeCommand(Map<String, Object> conditionMap, String ip) throws EncodeException, IOException {
        Map<String, Object> variableMap = (Map<String, Object>) conditionMap.get("variableSet");
        String wsToken = conditionMap.get("wsToken").toString();
        TSlider tSlider = getById(Integer.parseInt(conditionMap.get("id").toString()));
        List<TCommand> commandList = tCommandService.getCommandListByMain(tSlider.getId(), tSlider.getType(), "slide");
        tCommandService.executeCommandsAndGetReply(commandList, variableMap, wsToken, ip);

    }

    @Override
    public List<TSlider> getSliderIdsByPageId(Integer pageId) {
        List<TSlider> list = lambdaQuery()
                .select(TSlider::getId)
                .eq(TSlider::getPageId, pageId)
                .list();
        return list;
    }
}
